﻿Imports System.Net
Imports System.Data
Imports System.Xml
Imports System.IO
Imports System.Web
Imports System.Text
Imports System.Windows.Controls
Imports System.Collections.Specialized

'Imports System.Windows.Controls.DataVisualization

Class MainWindow

    Private _SearchService As SearchService.QueryService
    Private _metaDS As DataSet
    Private _queryTypesMS As StringCollection
    Private _queryTypesFAST As StringCollection
    Private _isMetaDataRetrieved As Boolean = False

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        _queryTypesMS = New StringCollection()
        _queryTypesMS.AddRange({"equals", "contains"})

        _queryTypesFAST = New StringCollection()
        _queryTypesFAST.AddRange({"contains", "ends-with", "equals", "starts-with", "less-than", "greater-than", "range"})

        Dim sortCollection As New StringCollection()
        sortCollection.AddRange({"Ascending", "Descending"})
        Me.cboSortByDirection.ItemsSource = sortCollection
        Me.cboSortByDirection.SelectedIndex = 1

        DirectCast(Me.dgMetadata.Columns.Item(7), DataGridComboBoxColumn).ItemsSource = _queryTypesFAST

        ' Add any initialization after the InitializeComponent() call.
        Me.txtUsername.Text = My.Settings.Username
        Me.txtDomain.Text = My.Settings.Domain
        Me.txtSiteUrl.Text = My.Settings.Url
        Me.txtNumResults.Text = My.Settings.ResultsReturned

        Me.txtDefaultPropertiesFAST.Text = My.Settings.DefaultPropertiesFAST
        Me.txtDefaultPropertiesMOSS.Text = My.Settings.DefaultPropertiesMOSS

        Me.chkEnableStemming.IsChecked = My.Settings.EnableStemming
        Me.chkTrimDuplicates.IsChecked = My.Settings.TrimDuplicates
        Me.chkImplicitAndBehavior.IsChecked = My.Settings.ImplicitAndBehavior
        Me.chkIncRelevantResults.IsChecked = My.Settings.IncludeRelevantResults
        Me.chkIncSpecialTermsResults.IsChecked = My.Settings.IncludeSpecialTermsResults

        Me.cboQueryLanguage.SelectedValue = My.Settings.QueryLanguage
        Me.cboResultProvider.SelectedValue = My.Settings.ResultsProvider
        Me.cboEnableSpellCheck.SelectedValue = My.Settings.EnableSpellcheck
    End Sub

    Private Sub MainWindow_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Closing
        'Store all of the settings for future use
        My.Settings.Username = Me.txtUsername.Text.Trim()
        My.Settings.Domain = Me.txtDomain.Text.Trim()
        My.Settings.Url = Me.txtSiteUrl.Text.Trim()
        My.Settings.ResultsReturned = Me.txtNumResults.Text.Trim()

        My.Settings.QueryLanguage = Me.cboQueryLanguage.SelectedValue
        My.Settings.ResultsProvider = Me.cboResultProvider.SelectedValue
        My.Settings.EnableSpellcheck = Me.cboEnableSpellCheck.SelectedValue

        My.Settings.EnableStemming = Me.chkEnableStemming.IsChecked
        My.Settings.TrimDuplicates = Me.chkTrimDuplicates.IsChecked
        My.Settings.ImplicitAndBehavior = Me.chkImplicitAndBehavior.IsChecked
        My.Settings.IncludeRelevantResults = Me.chkIncRelevantResults.IsChecked
        My.Settings.IncludeSpecialTermsResults = Me.chkIncSpecialTermsResults.IsChecked

        My.Settings.DefaultPropertiesFAST = Me.txtDefaultPropertiesFAST.Text
        My.Settings.DefaultPropertiesMOSS = Me.txtDefaultPropertiesMOSS.Text

        My.Settings.Save()
    End Sub

    Private Function InitWS() As Boolean

        Try

            Dim username As String = Me.txtUsername.Text.Trim()
            Dim password As String = Me.txtPassword.Password
            Dim domain As String = Me.txtDomain.Text.Trim()

            Dim creds As System.Net.NetworkCredential
            If domain <> String.Empty Then
                creds = New System.Net.NetworkCredential(username, password, domain)
            Else
                creds = New System.Net.NetworkCredential(username, password)
            End If

            Dim site As String = Me.txtSiteUrl.Text.Trim()
            If site.EndsWith("/") Then
                site = site + "_vti_bin/search.asmx"
            Else
                site = site + "/_vti_bin/search.asmx"
            End If

            _SearchService = New SearchService.QueryService
            _SearchService.Url = site
            _SearchService.PreAuthenticate = True
            _SearchService.UseDefaultCredentials = False
            _SearchService.Credentials = creds

            ServicePointManager.ServerCertificateValidationCallback = AddressOf ServerCertificateValidationCallback

        Catch ex As Exception
            MessageBox.Show(ex.Message)
            Return False
        End Try

        Return True

    End Function

    Private Sub btnGetMetadata_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnGetMetadata.Click
        GetMetaData()
    End Sub

    Private Function GetMetaData() As Boolean
        Me.Cursor = Cursors.Wait

        If InitWS() Then

            Try

                _metaDS = _SearchService.GetSearchMetadata()
                Dim dc As DataColumn = Nothing
                Dim xrankTable As DataTable = Nothing

                'Add other columns
                If _metaDS IsNot Nothing Then

                    If _metaDS.Tables("FASTSearchProperties") IsNot Nothing Then


                        xrankTable = _metaDS.Tables("FASTSearchProperties").Copy()
                        xrankTable.TableName = "FASTXrankProperties"

                        dc = New DataColumn("BoostTerm", GetType(System.String))
                        dc.DefaultValue = ""
                        xrankTable.Columns.Add(dc)

                        dc = New DataColumn("Weight", GetType(System.String))
                        dc.DefaultValue = ""
                        xrankTable.Columns.Add(dc)

                        dc = New DataColumn("QueryType", GetType(System.String))
                        dc.DefaultValue = "equals"
                        xrankTable.Columns.Add(dc)

                        dc = New DataColumn("BoostAll", GetType(System.String))
                        dc.DefaultValue = ""
                        xrankTable.Columns.Add(dc)


                        'Add criteria column
                        dc = New DataColumn("QueryTerm", GetType(System.String))
                        dc.DefaultValue = ""
                        _metaDS.Tables("FASTSearchProperties").Columns.Add(dc)

                        dc = New DataColumn("QueryType", GetType(System.String))
                        dc.DefaultValue = "equals"
                        _metaDS.Tables("FASTSearchProperties").Columns.Add(dc)

                        dc = New DataColumn("SortBy", GetType(System.String))
                        dc.DefaultValue = "ASC"
                        _metaDS.Tables("FASTSearchProperties").Columns.Add(dc)

                        dc = New DataColumn("IncludeInRefiner", GetType(System.Boolean))
                        dc.DefaultValue = False
                        _metaDS.Tables("FASTSearchProperties").Columns.Add(dc)

                        dc = New DataColumn("IncludeInResults", GetType(System.Boolean))
                        dc.DefaultValue = False

                        _metaDS.Tables("FASTSearchProperties").Columns.Add(dc)


                        _metaDS.Tables.Add(xrankTable)
                        _metaDS.Tables("FASTSearchProperties").AcceptChanges()
                        _metaDS.AcceptChanges()

                        xrankTable.AcceptChanges()

                        _metaDS.Tables("FASTSearchProperties").DefaultView.Sort = "Name ASC"

                        xrankTable.DefaultView.Sort = "Name ASC"
                    End If

                End If

                'Add Columns to Scopes
                dc = New DataColumn("AddScope", GetType(System.Boolean))
                dc.DefaultValue = False
                _metaDS.Tables("Scopes").Columns.Add(dc)


                'Add criteria column
                dc = New DataColumn("Refinable", GetType(System.Boolean))
                dc.DefaultValue = False
                _metaDS.Tables("Properties").Columns.Add(dc)

                dc = New DataColumn("QueryTerm", GetType(System.String))
                dc.DefaultValue = ""
                _metaDS.Tables("Properties").Columns.Add(dc)

                dc = New DataColumn("QueryType", GetType(System.String))
                dc.DefaultValue = "equals"
                _metaDS.Tables("Properties").Columns.Add(dc)

                dc = New DataColumn("SortBy", GetType(System.String))
                dc.DefaultValue = "ASC"
                _metaDS.Tables("Properties").Columns.Add(dc)

                dc = New DataColumn("IncludeInRefiner", GetType(System.Boolean))
                dc.DefaultValue = False
                _metaDS.Tables("Properties").Columns.Add(dc)

                dc = New DataColumn("IncludeInResults", GetType(System.Boolean))
                dc.DefaultValue = False
                _metaDS.Tables("Properties").Columns.Add(dc)



                _metaDS.Tables("Properties").DefaultView.Sort = "Name ASC"
                _metaDS.Tables("Scopes").DefaultView.Sort = "Name ASC"


                'Me.txtQuery.Text = metaDS.GetXml
                Me.dgScopes.DataContext = _metaDS.Tables("Scopes")

                Dim selectedResultProvider As String = DirectCast(cboResultProvider.SelectedItem, ComboBoxItem).Content
                If selectedResultProvider = "FAST" Then
                    If _metaDS.Tables("FASTSearchProperties") IsNot Nothing Then
                        Me.dgMetadata.DataContext = _metaDS.Tables("FASTSearchProperties")
                        Me.dgXRANK.DataContext = xrankTable
                        DirectCast(Me.dgXRANK.Columns.Item(1), DataGridComboBoxColumn).ItemsSource = _queryTypesFAST
                    End If
                Else
                    Me.dgMetadata.DataContext = _metaDS.Tables("Properties")
                End If

                SetSortingProperties()

                'Populate the TrimDuplicates Properties
                Dim mpNames As New StringCollection
                Dim managedPropertyXDoc As XDocument = XDocument.Load(New StringReader(_metaDS.GetXml()))
                Dim mpXElements As IEnumerable(Of XElement) =
                    From rp In managedPropertyXDoc.Descendants("FASTSearchProperties") _
                    Where rp.Element("Type").Value = "System.Int32" _
                    Select rp

                For Each mpXElement As XElement In mpXElements
                    'txtDataSet.Text = txtDataSet.Text & kalEl.ToString()

                    Dim propName As String
                    propName = mpXElement.Element("Name").Value

                    mpNames.Add(propName)
                Next
                ArrayList.Adapter(mpNames).Sort()
                Me.cboTrimDuplicateOnProp.ItemsSource = mpNames


                _isMetaDataRetrieved = True
            Catch ex As Exception
                Me.Cursor = Cursors.Arrow
                MessageBox.Show(ex.Message)
                Return False
            End Try

        End If

        Me.Cursor = Cursors.Arrow
        Return True

    End Function

    Private Sub btnGenerateQuery_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnGenerateQuery.Click
        If _isMetaDataRetrieved = True Then
            'Create the QueryXML
            CreateQueryXml2()
        Else
            'Get the MetaData first then create the query xml
            If GetMetaData() Then
                CreateQueryXml2()
            End If
        End If
    End Sub

    Private Sub btnRunQuery_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnRunQuery.Click
        InitWS()

        Me.Cursor = Cursors.Wait

        Try

            Dim queryText As String = Me.txtQuery.Text
            Dim resultsXmlString As String = _SearchService.Query(queryText)

            Dim resultsWin As New ResultsWindow
            'resultsWin.SetXml(resultsXmlString)
            resultsWin.SetResultsWinProperties_Query(queryText, resultsXmlString)
            'resultsWin.Query = queryText
            resultsWin.Username = Me.txtUsername.Text.Trim()
            resultsWin.Password = Me.txtPassword.Password
            resultsWin.Domain = Me.txtDomain.Text.Trim()
            resultsWin.WebserviceUrl = Me.txtSiteUrl.Text.Trim()

            resultsWin.Show()

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

        Me.Cursor = Cursors.Arrow

    End Sub



    Private Sub btnRunQueryEx_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnRunQueryEx.Click
        InitWS()

        Me.Cursor = Cursors.Wait

        Try

            Dim queryText As String = Me.txtQuery.Text
            Dim resultsDS As DataSet = _SearchService.QueryEx(queryText)

            Dim resultsWin As New ResultsWindow
            resultsWin.SetResultsWinProperties_QueryEx(queryText, resultsDS)
            'resultsWin.Query = queryText
            resultsWin.Username = Me.txtUsername.Text.Trim()
            resultsWin.Password = Me.txtPassword.Password
            resultsWin.Domain = Me.txtDomain.Text.Trim()
            resultsWin.WebserviceUrl = Me.txtSiteUrl.Text.Trim()

            resultsWin.Show()

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try

        Me.Cursor = Cursors.Arrow


    End Sub

    Private Sub cboResultProvider_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles cboResultProvider.SelectionChanged
        Dim selectedItem As ComboBoxItem = DirectCast(cboResultProvider.SelectedItem, ComboBoxItem)

        If selectedItem.Content = "FAST" Then
            Dim intQL As Integer = cboQueryLanguage.Items.Count - 1
            Dim intRemove As Integer = 0

            'For intRemove = 0 To intQL
            '    cboQueryLanguage.Items.RemoveAt(0)
            'Next intRemove

            cboQueryLanguage.Items.Clear()

            Dim cboItem1 As New ComboBoxItem
            cboItem1.Content = "FQL"
            cboItem1.IsSelected = True

            Dim cboItem2 As New ComboBoxItem
            cboItem2.Content = "Keyword"

            cboQueryLanguage.Items.Add(cboItem1)
            cboQueryLanguage.Items.Add(cboItem2)

            If _metaDS IsNot Nothing Then
                'Set the Table
                Me.dgMetadata.DataContext = _metaDS.Tables("FASTSearchProperties")

                SetSortingProperties()
            End If

            If dgMetadata IsNot Nothing Then
                DirectCast(Me.dgMetadata.Columns.Item(7), DataGridComboBoxColumn).ItemsSource = _queryTypesFAST
            End If


        Else

            Dim intQL As Integer = cboQueryLanguage.Items.Count - 1
            Dim intRemove As Integer = 0

            cboQueryLanguage.Items.Clear()

            Dim cboItem1 As New ComboBoxItem
            cboItem1.Content = "MSSQL"
            cboItem1.IsSelected = True

            Dim cboItem2 As New ComboBoxItem
            cboItem2.Content = "Keyword"

            cboQueryLanguage.Items.Add(cboItem1)
            cboQueryLanguage.Items.Add(cboItem2)


            If _metaDS IsNot Nothing Then
                Me.dgMetadata.DataContext = _metaDS.Tables("Properties")

                SetSortingProperties()
            End If

            If dgMetadata IsNot Nothing Then
                DirectCast(Me.dgMetadata.Columns.Item(7), DataGridComboBoxColumn).ItemsSource = _queryTypesMS
            End If

        End If
    End Sub

    Private Function CreateQueryText() As String

        Dim returnQuery As String = String.Empty

        Dim selectedQueryLanguage As String = DirectCast(Me.cboQueryLanguage.SelectedItem(), ComboBoxItem).Content

        If selectedQueryLanguage = "FQL" Then

            'Call MakeFQLQuery and set to the return string
            returnQuery = MakeFQLQuery()

        ElseIf selectedQueryLanguage = "Keyword" Then

            'Call MakeKeywordQuery and set to the return string
            returnQuery = MakeKeywordQuery()

        ElseIf selectedQueryLanguage = "MSSQL" Then

            'Call MakeMSSQLQuery and set to the return string
            returnQuery = MakeMSSQLQuery()

        End If

        Return returnQuery

    End Function

    Private Function MakeMSSQLQuery() As String

        Dim dt As DataTable = DirectCast(Me.dgMetadata.DataContext, DataTable)
        Dim managedPropertyXDoc As XDocument = XDocument.Load(New StringReader(dt.DataSet.GetXml()))

        Dim returnQuery As String = String.Empty
        Dim sqlQueryBuilder As New StringBuilder()
        Dim queryText As String = Me.txtQueryTerms.Text.Trim()

        Dim defaultPropList As String()
        defaultPropList = Me.txtDefaultPropertiesMOSS.Text.Trim.Split({","}, System.StringSplitOptions.RemoveEmptyEntries)
        Dim selectPropertyCollection As New ArrayList(defaultPropList)

        'add the required fields
        'Title, Path, Description, Write, Rank, Size
        'Dim selectPropertyCollection As New StringCollection
        'selectPropertyCollection.AddRange({"Rank", "Title", "Path", "Description", "Write", "Size"})

        'Add Additional Properties
        Dim managedPropeties As IEnumerable(Of XElement) =
            From cp In managedPropertyXdoc.Descendants("Properties") _
            Where cp.Element("IncludeInResults").Value = True _
            Select cp

        'Get the list of properties to return
        For Each mp As XElement In managedPropeties

            Dim propName As String
            propName = mp.Element("Name").Value

            If mp.Element("Retrievable").Value = False Then
                MessageBox.Show("Managed Property: " & propName & vbCrLf & "Not retrievable", "Error", MessageBoxButton.OK, MessageBoxImage.Error)
                Return String.Empty
            End If

            If Not selectPropertyCollection.Contains(propName.ToLower()) Then
                selectPropertyCollection.Add(propName.ToLower())
            End If

            'selectPropertyCollection.Add(propName.ToLower())
        Next

        'Create the select statement
        sqlQueryBuilder.Append("Select ")

        Dim queryLoop As Integer = 1

        For Each selectProperty As String In selectPropertyCollection

            sqlQueryBuilder.Append(selectProperty)

            If queryLoop < selectPropertyCollection.Count Then
                sqlQueryBuilder.Append(", ")
            End If

            queryLoop = queryLoop + 1

        Next

        sqlQueryBuilder.Append(" FROM Scope() ")

        'Add the scope to the queryCollection
        Dim dts As DataTable = DirectCast(Me.dgScopes.DataContext, DataTable)

        Dim scopeXDoc As XDocument = XDocument.Load(New StringReader(dts.DataSet.GetXml()))
        'Get the scopes to Add

        Dim scopeXElements As IEnumerable(Of XElement) =
                From sp In scopeXDoc.Descendants("Scopes") _
                Where sp.Element("AddScope").Value = True _
                Select sp


        'Get the managedProps to Add
        Dim queryMPXElements As IEnumerable(Of XElement) =
                From rp In managedPropertyXdoc.Descendants("Properties") _
                Where rp.Element("QueryTerm").Value <> String.Empty _
                Select rp


        'Create the WHERE clause 
        If queryText <> String.Empty OrElse queryMPXElements.Count > 0 OrElse scopeXElements.Count > 0 Then

            Dim whereBuilder As New StringBuilder()
            whereBuilder.Append("WHERE ")

            'look for keyword search
            If queryText <> "" Then

                Dim queryTextOption As String = DirectCast(cboQTPredicate.SelectedItem, ComboBoxItem).Content

                If queryTextOption = "CONTAINS" Then

                    whereBuilder.Append("CONTAINS ('""" & queryText & """') ")

                Else

                    whereBuilder.Append("FREETEXT(DefaultProperties, '")

                    'ENCODE SearchTerms and append; SINGLE QUOTES, FOR EXAMPLE, WILL CAUSE AN ERROR
                    whereBuilder.Append(EncodeCriteria(queryText) & "') ")

                End If

            End If

            Dim propertyQueryCollection As New StringCollection

            If queryMPXElements.Count > 0 Then

                For Each queryMP As XElement In queryMPXElements

                    Dim mpName As String = queryMP.Element("Name").Value
                    Dim mpQueryTerm As String = queryMP.Element("QueryTerm").Value
                    Dim mpDataType As String = queryMP.Element("Type").Value

                    Dim mpQueryType As String = queryMP.Element("QueryType").Value.ToLower()

                    If mpQueryType = "equals" Then
                        propertyQueryCollection.Add("(""" & mpName & """ = '" & mpQueryTerm & "')")
                    ElseIf mpQueryType = "contains" Then
                        propertyQueryCollection.Add("CONTAINS(""" & mpName & """, '" & mpQueryTerm & "')")
                    End If

                Next

            End If

            Dim scopeQueryCollection As New StringCollection

            If scopeXElements.Count > 0 Then

                For Each scope As XElement In scopeXElements

                    Dim scopeName As String = scope.Element("Name").Value
                    scopeQueryCollection.Add("(""SCOPE""='" & scopeName & "')")

                Next

            End If

            'Now construct the end of the WHERE clause

            Dim propLoop As Integer = 1
            For Each propertyQuery As String In propertyQueryCollection

                If propLoop = 1 And queryText <> String.Empty Then
                    whereBuilder.Append(" AND ")
                End If

                whereBuilder.Append(propertyQuery)

                If propLoop < propertyQueryCollection.Count Then
                    whereBuilder.Append(" AND ")
                End If

                propLoop = propLoop + 1

            Next

            If scopeQueryCollection.Count > 0 Then

                If queryText <> String.Empty Or propertyQueryCollection.Count > 0 Then
                    whereBuilder.Append(" AND ")
                End If

                whereBuilder.Append("(")

                Dim intScopeCount As Integer = 1
                For Each scopeQuery As String In scopeQueryCollection

                    If intScopeCount <> 1 Then
                        whereBuilder.Append(" OR ")
                    End If

                    whereBuilder.Append(scopeQuery)

                    intScopeCount = intScopeCount + 1

                Next

                whereBuilder.Append(")")

            End If

            whereBuilder.Append(" ORDER BY ""Rank"" DESC")

            Return sqlQueryBuilder.ToString & whereBuilder.ToString()

        End If

        Return String.Empty

    End Function

    Private Function MakeKeywordQuery() As String

        Dim dt As DataTable = DirectCast(Me.dgMetadata.DataContext, DataTable)
        Dim managedPropertyXDoc As XDocument = XDocument.Load(New StringReader(dt.DataSet.GetXml()))

        Dim returnQuery As String = String.Empty
        Dim queryCollection As New StringCollection

        'Add the query terms to the queryCollection
        queryCollection.Add(Me.txtQueryTerms.Text.Trim)

        'Add the scope to the queryCollection
        Dim dts As DataTable = DirectCast(Me.dgScopes.DataContext, DataTable)
        Dim scopeXDoc As XDocument = XDocument.Load(New StringReader(dts.DataSet.GetXml()))

        Dim scopeXElements As IEnumerable(Of XElement) =
                From sp In scopeXDoc.Descendants("Scopes") _
                Where sp.Element("AddScope").Value = True _
                Select sp

        If scopeXElements.Count > 0 Then

            'Loop through the Elements to create a queryText string
            For Each scopeXElement As XElement In scopeXElements
                Dim scopeName As String = String.Empty
                scopeName = scopeXElement.Element("Name").Value

                queryCollection.Add("scope:""" & scopeName & """")
            Next

        End If

        Dim mpXElements As IEnumerable(Of XElement) =
                From rp In managedPropertyXdoc.Descendants("FASTSearchProperties") _
                Where rp.Element("QueryTerm").Value <> String.Empty _
                Select rp

        If mpXElements.Count > 0 Then

            'Loop through the Elements to create a queryText string
            For Each mpElement As XElement In mpXElements

                If mpElement.Element("FullTextQueriable").Value = True Then

                    Dim mpName As String = mpElement.Element("Name").Value.ToLower()
                    Dim mpQueryType As String = mpElement.Element("QueryType").Value
                    Dim mpQueryTerm As String = mpElement.Element("QueryTerm").Value

                    Dim filterQuery As String = String.Format("{0}:""{1}""", mpName, mpQueryTerm)
                    'queryText.Append(query & " ")
                    queryCollection.Add(filterQuery)

                End If

            Next

        End If

        Dim queryBuilder As New StringBuilder
        For Each query As String In queryCollection

            queryBuilder.Append(query & " ")

        Next

        returnQuery = queryBuilder.ToString()

        Return returnQuery

    End Function

    Private Function MakeFQLQuery() As String

        Dim dt As DataTable = DirectCast(Me.dgMetadata.DataContext, DataTable)
        Dim managedPropertyXDoc As XDocument = XDocument.Load(New StringReader(dt.DataSet.GetXml()))

        Dim strQueryCollection As New StringCollection
        Dim queryTerms As String = Me.txtQueryTerms.Text.Trim()
        Dim strQuery As String = String.Empty

        Dim queryStringMode As String = DirectCast(cboStringMode.SelectedItem, ComboBoxItem).Content

        If queryTerms <> String.Empty Then
            'strQueryCollection.Add("string(""" & queryTerms & """)")
            strQueryCollection.Add(String.Format("string(""{0}"", Mode=""{1}"")", queryTerms, queryStringMode))
        End If

        Dim mpXElements As IEnumerable(Of XElement) =
            From rp In managedPropertyXDoc.Descendants("FASTSearchProperties") _
            Where rp.Element("QueryTerm").Value <> String.Empty _
            Select rp

        If mpXElements.Count > 0 Then

            'Loop through the Elements to create a queryText string
            For Each mpElement As XElement In mpXElements

                If mpElement.Element("FullTextQueriable").Value = True Then

                    Dim mpName As String = mpElement.Element("Name").Value.ToLower()
                    Dim mpQueryType As String = mpElement.Element("QueryType").Value
                    Dim mpQueryTerm As String = mpElement.Element("QueryTerm").Value
                    Dim mpType As String = mpElement.Element("Type").Value

                    Dim filterQuery As String = GetFilterQuery(mpElement)

                    'Dim filterQuery As String = String.Format("filter({0}:{1}({2}))", mpName, mpQueryType, mpQueryTerm)
                    'Dim filterQuery As String = String.Format("filter({0}:{1}(""{2}""))", mpName, mpQueryType, mpQueryTerm)
                    'queryText.Append(query & " ")
                    strQueryCollection.Add(filterQuery)

                End If

            Next

        End If

        'Take the query collection and create the query
        If strQueryCollection.Count > 0 Then
            If strQueryCollection.Count > 1 Then
                'Loop through the query collection and create the query text string
                Dim queryText As New StringBuilder

                queryText.Append("and(")

                Dim queryLoop As Integer = 1
                For Each query As String In strQueryCollection
                    queryText.Append(query)

                    If queryLoop < strQueryCollection.Count Then
                        queryText.Append(", ")
                    End If

                    queryLoop = queryLoop + 1
                Next

                queryText.Append(")")
                Dim returnQueryText As String = AddXRANKToQuery(queryText.ToString())
                Return returnQueryText
            Else
                Dim queryText As String = String.Empty
                queryText = strQueryCollection.Item(0)
                Dim returnQueryText = AddXRANKToQuery(queryText)
                Return returnQueryText
            End If
        Else
            'Nothing in the query return an empty string
            Return String.Empty
        End If

    End Function

    Private Function GetFilterQuery(ByVal mpElement As XElement) As String

        Dim returnQuery As String = String.Empty

        Dim mpName As String = mpElement.Element("Name").Value.ToLower()
        Dim mpQueryType As String = mpElement.Element("QueryType").Value
        Dim mpQueryTerm As String = mpElement.Element("QueryTerm").Value
        Dim mpType As String = mpElement.Element("Type").Value.ToLower()

        Select Case mpType

            Case "system.int32"
                returnQuery = GetFilterQueryInt(mpElement)
            Case "system.datetime"
                returnQuery = GetFilterQueryDateTime(mpElement)
            Case "system.string"
                returnQuery = GetFilterQueryString(mpElement)
            Case "system.boolean"
                returnQuery = GetFilterQueryBoolean(mpElement)
            Case "system.decimal"
                returnQuery = GetFilterQueryDecimal(mpElement)
            Case "system.float"
                returnQuery = GetFilterQueryFloat(mpElement)
            Case Else
                returnQuery = GetFilterQueryString(mpElement)
        End Select

        Return returnQuery

    End Function

    Private Function GetFilterQueryString(ByVal mpElement As XElement) As String
        Dim returnQuery As String = String.Empty

        Dim mpQueryType As String = mpElement.Element("QueryType").Value
        Dim mpQueryTerm As String = mpElement.Element("QueryTerm").Value
        Dim mpName As String = mpElement.Element("Name").Value.ToLower()

        Select Case mpQueryType
            Case "contains"
                mpQueryTerm = "string(""" & mpQueryTerm & """)"
                returnQuery = String.Format("filter({0}:{1})", mpName, mpQueryTerm)
            Case "equals"
                mpQueryTerm = """" & mpQueryTerm & """"
                returnQuery = String.Format("filter({0}:{1}({2}))", mpName, mpQueryType, mpQueryTerm)
            Case "starts-with"
                mpQueryTerm = """" & mpQueryTerm & """"
                returnQuery = String.Format("filter({0}:{1}({2}))", mpName, mpQueryType, mpQueryTerm)
            Case "ends-with"
                mpQueryTerm = """" & mpQueryTerm & """"
                returnQuery = String.Format("filter({0}:{1}({2}))", mpName, mpQueryType, mpQueryTerm)
            Case Else
                mpQueryTerm = "string(""" & mpQueryTerm & """)"
                returnQuery = String.Format("filter({0}:{1}({2}))", mpName, mpQueryType, mpQueryTerm)

        End Select

        Return returnQuery
    End Function

    Private Function GetFilterQueryDateTime(ByVal mpElement As XElement) As String
        Dim returnQuery As String = String.Empty

        Dim mpQueryType As String = mpElement.Element("QueryType").Value
        Dim mpQueryTerm As String = mpElement.Element("QueryTerm").Value
        Dim mpName As String = mpElement.Element("Name").Value.ToLower()

        If mpQueryType <> "range" Then
            Try
                mpQueryTerm = DateTime.Parse(mpQueryTerm).ToString("yyyy'-'MM'-'dd")
                'mpQueryTerm = DateTime.Parse(mpQueryTerm).ToString("yyyy'-'MM'-'ddTHH':'mm':'ss'Z'")
            Catch ex As Exception
                'Leave the Query Term Alone
            End Try
        End If

        Select Case mpQueryType
            Case "greater-than"
                mpQueryTerm = "datetime(""" & mpQueryTerm & """)"
                returnQuery = String.Format("filter({0}:range({1}, max, from=""GT""))", mpName, mpQueryTerm)
            Case "less-than"
                mpQueryTerm = "datetime(""" & mpQueryTerm & """)"
                returnQuery = String.Format("filter({0}:range(min,{1}, to=""LT""))", mpName, mpQueryTerm)
            Case "equals"
                mpQueryTerm = "datetime(""" & mpQueryTerm & """)"
                returnQuery = String.Format("filter({0}:{1})", mpName, mpQueryTerm)
            Case "range"
                Try

                    Dim dateStringArray As String() = mpQueryTerm.Split(",")
                    Dim minDate As String = dateStringArray(0)
                    Dim maxDate As String = dateStringArray(1)

                    Dim minDateString As String = DateTime.Parse(minDate).ToString("yyyy'-'MM'-'dd")
                    Dim maxDateString As String = DateTime.Parse(maxDate).ToString("yyyy'-'MM'-'dd")

                    minDateString = "datetime(""" & minDateString & """)"
                    maxDateString = "datetime(""" & maxDateString & """)"

                    returnQuery = String.Format("filter({0}:range({1}, {2}))", mpName, minDateString, maxDateString)

                Catch ex As Exception
                    returnQuery = String.Format("filter(DATEFORMATERROR)", mpName, mpQueryTerm)
                End Try
            Case Else
                mpQueryTerm = "datetime(""" & mpQueryTerm & """)"
                returnQuery = String.Format("filter({0}:{1})", mpName, mpQueryTerm)

        End Select

        Return returnQuery
    End Function

    Private Function GetFilterQueryInt(ByVal mpElement As XElement) As String
        Dim returnQuery As String = String.Empty

        Dim mpQueryType As String = mpElement.Element("QueryType").Value
        Dim mpQueryTerm As String = mpElement.Element("QueryTerm").Value
        Dim mpName As String = mpElement.Element("Name").Value.ToLower()

        Select Case mpQueryType
            Case "greater-than"
                'size:range(min, 500, to="LT")
                returnQuery = String.Format("filter({0}:range({1}, max, from=""GT""))", mpName, mpQueryTerm)
            Case "less-than"
                'size:range(min, 500, to="LT")
                returnQuery = String.Format("filter({0}:range(min,{1}, to=""LT""))", mpName, mpQueryTerm)
            Case "equals"
                returnQuery = String.Format("filter({0}={1})", mpName, mpQueryTerm)
            Case "range"
                returnQuery = String.Format("filter({0}:range({1}, from=""GE"", to=""LT""))", mpName, mpQueryTerm)
            Case Else
                returnQuery = String.Format("filter({0}={1})", mpName, mpQueryTerm)
        End Select

        Return returnQuery
    End Function

    Private Function GetFilterQueryDecimal(ByVal mpElement As XElement) As String
        Dim returnQuery As String = String.Empty

        Dim mpQueryType As String = mpElement.Element("QueryType").Value
        Dim mpQueryTerm As String = mpElement.Element("QueryTerm").Value
        Dim mpName As String = mpElement.Element("Name").Value.ToLower()

        Select Case mpQueryType
            Case "greater-than"
                'size:range(min, 500, to="LT")
                returnQuery = String.Format("filter({0}:range({1}, max, from=""GT""))", mpName, mpQueryTerm)
            Case "less-than"
                'size:range(min, 500, to="LT")
                returnQuery = String.Format("filter({0}:range(min,{1}, to=""LT""))", mpName, mpQueryTerm)
            Case "equals"
                returnQuery = String.Format("filter({0}={1})", mpName, mpQueryTerm)
            Case "range"
                returnQuery = String.Format("filter({0}:range({1}, from=""GE"", to=""LT""))", mpName, mpQueryTerm)
            Case Else
                returnQuery = String.Format("filter({0}={1})", mpName, mpQueryTerm)
        End Select

        Return returnQuery
    End Function

    Private Function GetFilterQueryFloat(ByVal mpElement As XElement) As String
        Dim returnQuery As String = String.Empty

        Dim mpQueryType As String = mpElement.Element("QueryType").Value
        Dim mpQueryTerm As String = mpElement.Element("QueryTerm").Value
        Dim mpName As String = mpElement.Element("Name").Value.ToLower()

        Select Case mpQueryType
            Case "greater-than"
                'size:range(min, 500, to="LT")
                returnQuery = String.Format("filter({0}:range({1}, max, from=""GT""))", mpName, mpQueryTerm)
            Case "less-than"
                'size:range(min, 500, to="LT")
                returnQuery = String.Format("filter({0}:range(min,{1}, to=""LT""))", mpName, mpQueryTerm)
            Case "equals"
                returnQuery = String.Format("filter({0}={1})", mpName, mpQueryTerm)
            Case "range"
                returnQuery = String.Format("filter({0}:range({1}, from=""GE"", to=""LT""))", mpName, mpQueryTerm)
            Case Else
                returnQuery = String.Format("filter({0}={1})", mpName, mpQueryTerm)
        End Select

        Return returnQuery
    End Function

    Private Function GetFilterQueryBoolean(ByVal mpElement As XElement) As String
        Dim returnQuery As String = String.Empty

        Dim mpQueryType As String = mpElement.Element("QueryType").Value
        Dim mpQueryTerm As String = mpElement.Element("QueryTerm").Value
        Dim mpName As String = mpElement.Element("Name").Value.ToLower()

        Select Case mpQueryType
            Case "equals"
                returnQuery = String.Format("filter({0}={1})", mpName, mpQueryTerm)
            Case Else
                returnQuery = String.Format("filter({0}={1})", mpName, mpQueryTerm)
        End Select

        Return returnQuery
    End Function


    Private Function AddXRANKToQuery(ByVal queryText As String) As String

        Try
            If Me.chkXRANK.IsChecked Then

                Dim dt As DataTable = DirectCast(Me.dgXRANK.DataContext, DataTable)
                Dim managedPropertyXDoc As XDocument = XDocument.Load(New StringReader(dt.DataSet.GetXml()))
                Dim strQueryCollection As New StringCollection

                Dim mpXElements As IEnumerable(Of XElement) =
                        From rp In managedPropertyXDoc.Descendants("FASTXrankProperties") _
                        Where rp.Element("BoostTerm").Value <> String.Empty _
                        Select rp

                    For Each mp As XElement In mpXElements

                        Dim mpName As String = mp.Element("Name").Value.ToLower()
                        Dim mpQueryType As String = mp.Element("QueryType").Value
                    Dim mpQueryTerm As String = mp.Element("BoostTerm").Value

                        If mpQueryType.ToLower = "contains" Then
                            mpQueryType = "string"
                        End If

                        Dim filterQuery As String = String.Format("{0}:{1}(""{2}"")", mpName, mpQueryType, mpQueryTerm)
                        strQueryCollection.Add(filterQuery)

                    Next

                    If Me.txtXRANKBoostTerm.Text.Trim() <> String.Empty Then
                        Dim boostTerm As String = Me.txtXRANKBoostTerm.Text.Trim()
                        Dim boostQuery As String = String.Format("{0}(""{1}"")", "string", boostTerm)

                        strQueryCollection.Add(boostQuery)

                End If


                If strQueryCollection.Count > 0 Then
                        'Loop through the query collection and create the query text string
                    Dim xrankQueryText As New StringBuilder()
                    xrankQueryText.Append("xrank(" & queryText & ", ")

                    Dim queryLoop As Integer = 1
                    For Each query As String In strQueryCollection
                        xrankQueryText.Append(query)

                        If queryLoop < strQueryCollection.Count Then
                            xrankQueryText.Append(", ")
                        End If

                        queryLoop = queryLoop + 1
                    Next

                    Dim boostWeight As String = Me.txtXRANKWeight.Text.Trim()
                    If boostWeight = String.Empty Then
                        boostWeight = "100"
                    End If
                    xrankQueryText.Append(", boost=" & boostWeight)


                    Dim boostAll As String = DirectCast(Me.cboXRANKBoostAll.SelectedItem(), ComboBoxItem).Content
                    xrankQueryText.Append(", boostall=" & boostAll.ToLower())

                    xrankQueryText.Append(")")
                    Return xrankQueryText.ToString()

                Else
                    'Nothing in the query return an empty string
                    Return queryText
                End If


            Else
                'Use XRANK is not checked, return the queryText with no modifications
                Return queryText
            End If
        Catch ex As Exception
            Return queryText
        End Try

        Return queryText

    End Function

    Private Function EncodeCriteria(ByVal Value As String) As String

        Dim Ret As String

        'encode it
        Ret = WebUtility.HtmlEncode(Value)

        'doesn't get single quotes
        Ret = Ret.Replace("'", "%27")

        Return Ret

    End Function

    Private Sub cboQueryLanguage_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles cboQueryLanguage.SelectionChanged

        If cboQueryLanguage.SelectedItem IsNot Nothing Then


            Dim selectedQueryLanguage As String = DirectCast(Me.cboQueryLanguage.SelectedItem(), ComboBoxItem).Content

            If selectedQueryLanguage = "FQL" Then
                dgScopes.IsEnabled = False
                'If cboQTPredicate IsNot Nothing Then
                '    Me.cboQTPredicate.IsEnabled = False
                'End If
            ElseIf selectedQueryLanguage = "Keyword" Then
                dgScopes.IsEnabled = True

                'If cboQTPredicate IsNot Nothing Then
                '    Me.cboQTPredicate.IsEnabled = False
                'End If

                ElseIf selectedQueryLanguage = "MSSQL" Then
                    dgScopes.IsEnabled = True

                'If cboQTPredicate IsNot Nothing Then
                '    Me.cboQTPredicate.IsEnabled = True
                'End If

                End If


            End If

    End Sub

    Private Sub chkTrimDuplicatesSetProperty_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles chkTrimDuplicatesSetProperty.Checked
            Me.txtTrimDuplicateKC.IsEnabled = True
        Me.cboTrimDuplicateOnProp.IsEnabled = True
        Me.chkTrimDuplicatesIncludeID.IsEnabled = True
    End Sub

    Private Sub chkTrimDuplicatesSetProperty_Unchecked(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles chkTrimDuplicatesSetProperty.Unchecked
        Me.txtTrimDuplicateKC.IsEnabled = False
        Me.cboTrimDuplicateOnProp.IsEnabled = False
        Me.chkTrimDuplicatesIncludeID.IsEnabled = False
    End Sub

    Private Sub CreateQueryXml2()

        Me.Cursor = Cursors.Wait

        Try

            Dim dt As DataTable = DirectCast(Me.dgMetadata.DataContext, DataTable)
            Dim managedPropertyXDoc As XDocument = XDocument.Load(New StringReader(dt.DataSet.GetXml()))

            Dim queryXDoc As New XDocument

            Dim queryPacketXE As New XElement("QueryPacket")
            queryPacketXE.SetAttributeValue("Revision", "1000")

            Dim queryXE As New XElement("Query")
            Dim contextXE As New XElement("Context")
            Dim queryTextXE As XElement = GetQueryTextElement()

            Dim suportedFormatsXE As New XElement("SupportedFormats")
            suportedFormatsXE.SetAttributeValue("Format", "urn:Microsoft.Search.Response.Document.Document")

            Dim resultProviderXE As XElement = GetSelectedProviderElement()
            Dim rangeXE As XElement = GetRangeElement()
            Dim enableStemmingXE As New XElement("EnableStemming", IIf(chkEnableStemming.IsChecked, "true", "false"))
            Dim sortByPropertiesXE As XElement = GetSortByPropertiesElement()

            Dim enableSpellCheckXE As XElement = New XElement("EnableSpellCheck", DirectCast(cboEnableSpellCheck.SelectedItem, ComboBoxItem).Content)

            Dim trimDuplicatesXE As XElement = GetTrimDuplicatesElement()

            Dim incSpecialTermsResultsXE As XElement = New XElement("IncludeSpecialTermsResults", IIf(chkIncSpecialTermsResults.IsChecked, "true", "false"))
            Dim incRelevantResultsXE As XElement = New XElement("IncludeRelevantResults", IIf(chkIncRelevantResults.IsChecked, "true", "false"))
            Dim implicitAndBehaviorXE As XElement = New XElement("ImplicitAndBehavior", IIf(chkImplicitAndBehavior.IsChecked, "true", "false"))
            Dim includeRefinementResultsXE As XElement = GetIncludeRefinementResultsElement()
            Dim propertiesXE As XElement = GetReturnPropertiesElement()

            'Assemble the xml
            contextXE.Add(queryTextXE)
            queryXE.Add(contextXE)

            queryXE.Add(suportedFormatsXE)

            If resultProviderXE IsNot Nothing Then
                queryXE.Add(resultProviderXE)
            End If

            If rangeXE IsNot Nothing Then
                queryXE.Add(rangeXE)
            End If

            If enableStemmingXE IsNot Nothing Then
                queryXE.Add(enableStemmingXE)
            End If

            If enableSpellCheckXE IsNot Nothing Then
                queryXE.Add(enableSpellCheckXE)
            End If

            If incSpecialTermsResultsXE IsNot Nothing Then
                queryXE.Add(incSpecialTermsResultsXE)
            End If

            If incRelevantResultsXE IsNot Nothing Then
                queryXE.Add(incRelevantResultsXE)
            End If

            If implicitAndBehaviorXE IsNot Nothing Then
                queryXE.Add(implicitAndBehaviorXE)
            End If

            If sortByPropertiesXE IsNot Nothing Then
                queryXE.Add(sortByPropertiesXE)
            End If

            If trimDuplicatesXE IsNot Nothing Then
                queryXE.Add(trimDuplicatesXE)
            End If

            If includeRefinementResultsXE IsNot Nothing Then
                queryXE.Add(includeRefinementResultsXE)
            End If

            If propertiesXE IsNot Nothing Then
                queryXE.Add(propertiesXE)
            End If

            If queryXE IsNot Nothing Then
                queryPacketXE.Add(queryXE)
            End If

            queryXDoc.Add(queryPacketXE)

            Me.txtQuery.Text = queryXDoc.ToString()

        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error Generating Query")
            Me.Cursor = Cursors.Arrow
        End Try

        Me.Cursor = Cursors.Arrow

    End Sub

    Private Sub SetSortingProperties()

        Dim selectedResultProvider As String = DirectCast(cboResultProvider.SelectedItem, ComboBoxItem).Content
        If selectedResultProvider = "FAST" Then

            'Set the sorting properties
            Dim managedPropertyXDoc As XDocument = XDocument.Load(New StringReader(_metaDS.GetXml()))
            Dim sortMPs As New StringCollection
            Dim mpNameXElements As IEnumerable(Of XElement) =
                From rp In managedPropertyXDoc.Descendants("FASTSearchProperties") _
                Where rp.Element("Sortable").Value = True _
                Select rp

            For Each mpNameXElement As XElement In mpNameXElements
                'txtDataSet.Text = txtDataSet.Text & kalEl.ToString()

                Dim propName As String
                propName = mpNameXElement.Element("Name").Value

                sortMPs.Add(propName)
            Next

            sortMPs.Add("Rank")
            ArrayList.Adapter(sortMPs).Sort()
            Me.cboSortPropName.ItemsSource = sortMPs
            Me.cboSortPropName.SelectedItem = "Rank"
            'Me.dgMetadata.ItemsSource = metaDS.Tables("FASTSearchProperties")

        Else

            'Set the sorting properties
            Dim managedPropertyXDoc As XDocument = XDocument.Load(New StringReader(_metaDS.GetXml()))
            Dim sortMPs As New StringCollection
            Dim mpNameXElements As IEnumerable(Of XElement) =
                From rp In managedPropertyXDoc.Descendants("Properties") _
                Select rp

            For Each mpNameXElement As XElement In mpNameXElements
                'txtDataSet.Text = txtDataSet.Text & kalEl.ToString()

                Dim propName As String
                propName = mpNameXElement.Element("Name").Value

                sortMPs.Add(propName)
            Next

            Me.cboSortPropName.ItemsSource = sortMPs

        End If

    End Sub

    Private Function GetIncludeRefinementResultsElement() As XElement
        Dim dt As DataTable = DirectCast(Me.dgMetadata.DataContext, DataTable)
        Dim managedPropertyXDoc As XDocument = XDocument.Load(New StringReader(dt.DataSet.GetXml()))

        Dim mpXElements As IEnumerable(Of XElement) =
            From rp In managedPropertyXDoc.Descendants("FASTSearchProperties")
            Where rp.Element("IncludeInRefiner").Value = True _
            Select rp

        If mpXElements.Count > 0 Then

            Dim incRRXE As New XElement("IncludeRefinementResults")
            Dim refinersXE As New XElement("Refiners")

            'xw.WriteStartElement("IncludeRefinementResults")
            'xw.WriteStartElement("Refiners")

            For Each mpXElement In mpXElements

                Dim propName As String
                propName = mpXElement.Element("Name").Value

                If mpXElement.Element("Refinable").Value = False Then
                    MessageBox.Show("Managed Property: " & propName & vbCrLf & "Not refinable", "Error", MessageBoxButton.OK, MessageBoxImage.Error)
                    'Exit Function
                End If

                Dim refinerXE As New XElement("Refiner", propName.ToLower())
                refinersXE.Add(refinerXE)

            Next

            Dim msrhXE As New XElement("MaxShallowRefinementHits", "100")
            incRRXE.Add(refinersXE)
            incRRXE.Add(msrhXE)

            Return incRRXE

        Else
            Return Nothing
        End If
    End Function

    Private Function GetTrimDuplicatesElement() As XElement

        Dim trimXE As New XElement("TrimDuplicates")
        trimXE.SetValue(True)

        'Create TrimDuplicates Node
        If chkTrimDuplicates.IsChecked Then

            If chkTrimDuplicatesSetProperty.IsChecked Then
                Dim trimPropName As String = cboTrimDuplicateOnProp.SelectedItem
                Dim keepCount As String = Me.txtTrimDuplicateKC.Text.Trim()

                If trimPropName Is Nothing Then
                    MessageBox.Show("Please select a Property as the Trim Duplicate basis", "Error", MessageBoxButton.OK)
                    Return Nothing
                Else
                    trimXE.SetAttributeValue("onproperty", trimPropName.ToLower())
                    trimXE.SetAttributeValue("keepcount", keepCount)
                    trimXE.SetValue(True)
                End If

                'This attribute doesn't work right now:
                'xw.WriteAttributeString("includeid", IIf(chkTrimDuplicatesIncludeID.IsChecked, "true", "false"))

            Else
                trimXE.SetValue(True)
            End If
        Else
            trimXE.SetValue(False)
        End If

        Return trimXE

    End Function

    Private Function GetQueryTextElement() As XElement

        Dim qtxe As New XElement("QueryText")
        qtxe.SetAttributeValue("language", txtLocale.Text.Trim())


        Dim selectedQueryLanguage As String = DirectCast(cboQueryLanguage.SelectedItem, ComboBoxItem).Content
        Dim qlString As String = String.Empty

        If selectedQueryLanguage = "FQL" Then
            qlString = "FQL"
        ElseIf selectedQueryLanguage = "MSSQL" Then
            qlString = "MSSQLFT"
        Else
            qlString = "STRING"
        End If

        qtxe.SetAttributeValue("type", qlString)

        Dim queryText As String = Me.CreateQueryText()
        qtxe.SetValue(queryText)

        Return qtxe

    End Function

   

    Private Function GetSelectedProviderElement() As XElement

        Dim selectedProviderElement As New XElement("ResultProvider")

        'Create ResultProvider Node
        Dim selectedResultProvider As String = DirectCast(cboResultProvider.SelectedItem, ComboBoxItem).Content
        Dim rpString As String
        If selectedResultProvider = "FAST" Then
            rpString = "FASTSearch"
        Else
            rpString = "SharepointSearch"
        End If

        selectedProviderElement.SetValue(rpString)

        Return selectedProviderElement
    End Function

    Private Function GetRangeElement() As XElement

        Dim rangeXE As New XElement("Range")
        rangeXE.SetElementValue("StartAt", txtStartNum.Text.Trim)
        rangeXE.SetElementValue("Count", txtNumResults.Text.Trim)

        Return rangeXE

    End Function

    Private Function GetSortByPropertiesElement() As XElement


        If Me.radSortByFQL.IsChecked Then

            Dim sortByPropertiesXE As New XElement("SortByProperties")
            Dim sortByPropertyXE As New XElement("SortByProperty")
            sortByPropertyXE.SetAttributeValue("name", Me.txtSortByFQL.Text.Trim())
            sortByPropertyXE.SetAttributeValue("direction", "FQLFormula")
            sortByPropertiesXE.Add(sortByPropertyXE)

            Return sortByPropertiesXE

        ElseIf Me.radSortByRankProfile.IsChecked Then

            Dim sortByPropertiesXE As New XElement("SortByProperties")
            Dim sortByPropertyXE As New XElement("SortByProperty")
            sortByPropertyXE.SetAttributeValue("name", Me.txtSortByRankProfile.Text.Trim())
            sortByPropertiesXE.Add(sortByPropertyXE)

            Return sortByPropertiesXE

        ElseIf Me.radSortByProp.IsChecked Then

            Dim sortByPropertiesXE As New XElement("SortByProperties")
            Dim sortByPropertyXE As New XElement("SortByProperty")
            sortByPropertyXE.SetAttributeValue("name", CStr(Me.cboSortPropName.SelectedItem).ToLower())
            sortByPropertyXE.SetAttributeValue("direction", Me.cboSortByDirection.SelectedItem)
            sortByPropertiesXE.Add(sortByPropertyXE)

            Return sortByPropertiesXE

        End If

        Return Nothing

    End Function

    Private Function GetReturnPropertiesElement() As XElement

        Dim dt As DataTable = DirectCast(Me.dgMetadata.DataContext, DataTable)
        Dim managedPropertyXDoc As XDocument = XDocument.Load(New StringReader(dt.DataSet.GetXml()))

        Dim propertiesXE As New XElement("Properties")

        Dim selectedResultProvider As String = DirectCast(cboResultProvider.SelectedItem, ComboBoxItem).Content

        If selectedResultProvider = "FAST" Then

            Dim defaultPropList As String()
            defaultPropList = Me.txtDefaultPropertiesFAST.Text.Trim.Split({","}, System.StringSplitOptions.RemoveEmptyEntries)

            Dim propList As New ArrayList(defaultPropList)

            'Add Additional Properties
            Dim krypton As IEnumerable(Of XElement) =
                From cp In managedPropertyXDoc.Descendants("FASTSearchProperties") _
                Where cp.Element("IncludeInResults").Value = True _
                Select cp

            For Each kalEl As XElement In krypton

                Dim propName As String
                propName = kalEl.Element("Name").Value

                If kalEl.Element("Retrievable").Value = False Then
                    MessageBox.Show("Managed Property: " & propName & vbCrLf & "Not retrievable", "Error", MessageBoxButton.OK, MessageBoxImage.Error)
                    'Exit Function
                End If

                If Not propList.Contains(propName) Then
                    'defaultPropList.
                    propList.Add(propName)
                End If

            Next

            For Each pName As String In propList
                Dim propertyXE As New XElement("Property")
                propertyXE.SetAttributeValue("name", pName)
                propertiesXE.Add(propertyXE)
            Next

        Else

            Dim defaultPropList As String()
            defaultPropList = Me.txtDefaultPropertiesMOSS.Text.Trim.Split({","}, System.StringSplitOptions.RemoveEmptyEntries)

            Dim propList As New ArrayList(defaultPropList)

            'Add Additional Properties
            Dim krypton As IEnumerable(Of XElement) =
                From cp In managedPropertyXDoc.Descendants("Properties") _
                Where cp.Element("IncludeInResults").Value = True _
                Select cp

            For Each kalEl As XElement In krypton

                Dim propName As String
                propName = kalEl.Element("Name").Value

                If kalEl.Element("Retrievable").Value = False Then
                    MessageBox.Show("Managed Property: " & propName & vbCrLf & "Not retrievable", "Error", MessageBoxButton.OK, MessageBoxImage.Error)
                    'Exit Function
                End If

                If Not propList.Contains(propName) Then
                    'defaultPropList.
                    propList.Add(propName)
                End If

            Next

            For Each pName As String In propList
                Dim propertyXE As New XElement("Property")
                propertyXE.SetAttributeValue("name", pName)
                propertiesXE.Add(propertyXE)
            Next

        End If

        Return propertiesXE

    End Function

    Private Function GetUserContextElement() As XElement


        '<UserContext includeuserprofile={true|false}>
        '<UserContextData includeuserprofile={true|false}>
        'userContextString()
        '</UserContextData>
        '</UserContext>


        Dim userContextXE As New XElement("UserContext")
        Dim userContextDataXE As New XElement("UserContextData")
        Dim contextGroupIDXE As New XElement("ContextGroupID")

        userContextDataXE.Value = Me.txtUserContextData.Text
        contextGroupIDXE.Value = Me.txtUserContextGroupID.Text

        userContextXE.Add(userContextDataXE)
        userContextXE.Add(contextGroupIDXE)

        Return userContextXE

    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        txtDefaultPropertiesFAST.Text = "Rank,Title,Author,Size,Path,Write,SiteName,HitHighlightedSummary,HitHighlightedProperties,ContentClass,IsDocument,Url,FileExtension,SpSiteUrl,docvector,fcocount,fcoid"
        txtDefaultPropertiesMOSS.Text = "Rank,Title,Author,Size,Path,Write,HitHighlightedSummary,HitHighlightedProperties"
    End Sub

    Public Shared Function ServerCertificateValidationCallback(ByVal sender As Object, _
    ByVal cert As System.Security.Cryptography.X509Certificates.X509Certificate, _
    ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, _
    ByVal sslPolicyErrors As System.Net.Security.SslPolicyErrors) As Boolean
        'this call back funciton is installed if the user chooses to ignore all cert errors.
        Return True
    End Function

    Private Sub winQuery_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        Me.txtSiteUrl.Focus()
    End Sub
End Class
